#include "./include/Semaphore_t.h"


Semaphore_t::Semaphore_t()
{
    this->value=0;
    this->lock=0;
}
/*
 * 函数功能：
 *     Semaphore_t的构造函数
 * 参数：
 *     无
 * 返回值：
 *     无
 */
Semaphore_t::Semaphore_t(int value)
{
    *this=value;
    this->lock=0;
}

/*
 * 函数功能：
 *     重载赋值运算符，使得可以将一个整数赋值给信号量对象
 * 参数：
 *     int value: 待赋值的整数
 * 返回值：
 *     当前this对象的引用
 */
Semaphore_t& Semaphore_t::operator=(int value)
{
    this->value=value;
    return *this;
}

/*
 * 函数功能：
 *     插入一段汇编，使其实现读后置1的功能，类似于 TSL 原子指令
 * 参数：
 *     int *pLock: 传入一个锁指针
 * 返回值：
 *     int：返回 *pLock 置 1 之前的值
 */
int TSL(int *pLock)
{
    /*
     * 定义一个临时变量 t，初始值为 1
     * 变量 t 的作用是与 *pLock 交换后返回
     * 实现对 *pLock 读后置 1 的功能 
     */
    int t=1; 

    /*
     * 以下采用 GCC 的内联汇编，因此本程序需要使用 GCC 编译器
     */
    __asm__
    (
        "movl  $1, %0 \n\t \
         xchg  %0, (%1) \n\t"    // xchg 指令会默认设置 lock，以保证指令的原子性
        :           // output
        "+r"(t)     // %0 -> t
        :           // input
        "r"(pLock)  // pLock -> %1
    );

    return t;
}

/*
 * 函数功能：
 *     信号量的P操作
 * 参数：
 *     Semaphore_t *pS: 传入一个信号量指针
 * 返回值：
 *     void
 */
void P(Semaphore_t *pS) 
{
    for(;;) {
        while( TSL(&(pS->lock)) );  // 调用 TSL 函数，通过汇编指令实现原子操作
        if(pS->value>0) {
            pS->value--;
            break;
        }
        pS->lock=0;
    }
    pS->lock=0;
}

/*
 * 函数功能：
 *     信号量的V操作
 * 参数：
 *     Semaphore_t *pS: 传入一个信号量指针
 * 返回值：
 *     void
 */
void V(Semaphore_t *pS) 
{
    // 对信号量指针 pS 进行互斥操作
    while( TSL(&(pS->lock)) ) ;
    pS->value++;
    pS->lock=0;
}

/*
 * 函数功能：
 *     获取信号量的值
 * 参数：
 *     Semaphore_t *pS: 传入一个信号量指针
 * 返回值：
 *     int，返回信号量的值
 */
int getSemaphoreValue(Semaphore_t *pS)
{
    if(pS) {
        return pS->value;
    }
    return 0;
}
